﻿package com.codingbros.particles 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	
	import flash.events.Event;
	
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author ...
	 */
	public class ParticleGridSystem extends ParticleSystem
	{
		private const COLORS:Array = new Array(0x291e38, 0x6b3849, 0xd3643b, 0x2c9bc4);
		
		private const GRIDSIZE:int = 40;
		private var gridWidthNum:int;
		private var gridHeightNum:int;
		
		private var noiseOffset:Array = new Array(new Point(), new Point());
		private var noiseOffsetAdd:Number = 0.9;
		
		private var particleDistortNoiseBitmap:Bitmap;
		private var particleDistortNoiseBitmapData:BitmapData;
		
		private var particleAmountNoiseBitmap:Bitmap;
		private var particleAmountNoiseBitmapData:BitmapData;

		
		public function ParticleGridSystem(width:int, height:int) 
		{
			super(width, height);
			
			gridWidthNum = width / GRIDSIZE + 1;
			gridHeightNum = height / GRIDSIZE + 1;
			
			numberOfParticles = gridWidthNum * gridHeightNum;
			
			
			for (var j:int = 0; j < particles.length; j ++) {
				particles[j] = new ColoredParticle();
			}			
			
			var p:Particle;
			
			for (var i:int = 0; i < particlesNum; i ++) 
			{
				p = particles[i];
				p.x = i % gridWidthNum * GRIDSIZE;
				p.y = int(i / gridWidthNum) * GRIDSIZE;
				
				p.vx = (0.5 - Math.random()) / 2;
				p.vy = (0.5 - Math.random()) / 2;
				
				ColoredParticle(p).color = COLORS[Math.floor(Math.random()*4)];
			}
			
			particleDistortNoiseBitmapData = new BitmapData(systemWidth, systemHeight);
			
			particleDistortNoiseBitmap = new Bitmap(particleDistortNoiseBitmapData);
			particleDistortNoiseBitmap.visible = false;
			this.addChild(particleDistortNoiseBitmap);	
			
			particleAmountNoiseBitmapData = new BitmapData(systemWidth, systemHeight);
			
			particleAmountNoiseBitmap = new Bitmap(particleAmountNoiseBitmapData);
			particleAmountNoiseBitmap.visible = false;
			this.addChild(particleAmountNoiseBitmap);	
			
		}
		
		override protected function updateSystem(e:Event):void 
		{
			particlesCanvas.graphics.clear();			
			
			var p:Particle;			
			var p2:Particle;
			var p3:Particle;
			var p4:Particle;
			
			for (var i:int = 0; i < particlesNum; i ++) 
			{				
				p = particles[i];
				//particlesCanvas.graphics.lineStyle(1, 0x000000);
				
				if ((i % gridWidthNum) + 1 < gridWidthNum 
				&& i < particlesNum - gridWidthNum 
				&& i + gridWidthNum + 1 < particlesNum) 
				{
					p2 = particles[i + 1];
					p3 = particles[i + gridWidthNum +1];
					p4 = particles[i + gridWidthNum];
					
					/*
					particlesCanvas.graphics.beginFill(ColoredParticle(p).color,  1 - Math.sin(Math.PI / 2 + Math.PI / 2 * ColoredParticle(p).alpha));
					particlesCanvas.graphics.moveTo(p.x, p.y);				
					particlesCanvas.graphics.lineTo(p2.x, p2.y);			
					particlesCanvas.graphics.lineTo(p3.x, p3.y);			
					particlesCanvas.graphics.lineTo(p4.x, p4.y);
				
					particlesCanvas.graphics.beginFill(0,ColoredParticle(p).alpha);
					particlesCanvas.graphics.moveTo(p.x, p.y);				
					particlesCanvas.graphics.lineTo(p2.x, p2.y);			
					particlesCanvas.graphics.lineTo(p3.x, p3.y);			
					particlesCanvas.graphics.lineTo(p4.x, p4.y);					
					*/
					
					particlesCanvas.graphics.lineStyle(1, 0x000000);
					particlesCanvas.graphics.moveTo(p.x, p.y);				
					particlesCanvas.graphics.lineTo(p.x + p.vx, p.y + p.vy);
					
				}
				particlesCanvas.graphics.endFill();
			}
			
			//particlesBitmapData.colorTransform(particlesBitmapData.rect, new ColorTransform( 1, 1, 1, 1, 0, 0, 0, -1 ) );
			particlesBitmapData.draw(particlesBackground);
			particlesBitmapData.draw(particlesCanvas);
			
			
			noiseOffset[0].x += noiseOffsetAdd;
			noiseOffset[0].y += noiseOffsetAdd;
			
			noiseOffset[1].x -= noiseOffsetAdd;
			noiseOffset[1].y -= noiseOffsetAdd;
			
			particleDistortNoiseBitmapData.perlinNoise(500, 500, 1, 100, false, true, 7, true, noiseOffset);
			
			particleAmountNoiseBitmapData.perlinNoise(80, 20, 1, 200, false, true, 7, true, noiseOffset);
			
			
			var brightness:Number;
			var radians:Number;
			var amount:Number;
			var posAmount:Number;
			
			for (var j:int = 0; j < particlesNum; j ++) 
			{							
				p = particles[j];				
								
				amount = particleAmountNoiseBitmapData.getPixel(p.x, p.y) / 0xFFFFFF;
				
				posAmount = (j % gridWidthNum / gridWidthNum) * ((j / gridHeightNum) / gridHeightNum);
				//posAmount = 1;
				
				brightness = particleDistortNoiseBitmapData.getPixel(p.x, p.y) / 0xFFFFFF;
				
				if (j == 0) trace(amount);
				
				ColoredParticle(p).alpha = 1 - amount * posAmount;
				
				radians = (Math.PI * 2) *  brightness;
				
				p.vx = Math.cos(radians) * PARTICLEMAXSPEED * 15;
				p.vy = Math.sin(radians) * PARTICLEMAXSPEED * 15;	
				
				p.x = j % gridWidthNum * GRIDSIZE + p.vx * amount * posAmount;
				p.y = int(j / gridWidthNum) * GRIDSIZE + p.vy * amount * posAmount;
				
				
			}
		}
		
	}
	
}